using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Domain.Services;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Text.Json;
using CKY.AgentPlatform.ModelConfigs;
using CKY.AgentPlatform.Domain.McpTools;
using CKY.AgentPlatform.Conversations;
using CKY.AgentPlatform.Common.Types;
using ChatMessage = CKY.AgentPlatform.Common.Types.ChatMessage;
using ToolCall = CKY.AgentPlatform.Common.Types.ToolCall;
using McpToolExecutionInput = CKY.AgentPlatform.Common.Types.McpToolExecutionInput;
using McpToolExecutionResult = CKY.AgentPlatform.Common.Types.McpToolExecutionResult;

namespace CKY.AgentPlatform.Agents
{
    /// <summary>
    /// Agent执行引擎 - 负责Agent的核心业务逻辑执行
    /// </summary>
    public class AgentExecutionEngine : DomainService
    {
        private readonly ILogger<AgentExecutionEngine> _logger;
        private readonly IModelExecutionService _modelExecutionService;
        private readonly IMcpToolExecutionService _mcpToolExecutionService;
        private readonly IPromptTemplateService _promptTemplateService;
        private readonly IConversationManager _conversationManager;

        public AgentExecutionEngine(
            ILogger<AgentExecutionEngine> logger,
            IModelExecutionService modelExecutionService,
            IMcpToolExecutionService mcpToolExecutionService,
            IPromptTemplateService promptTemplateService,
            IConversationManager conversationManager)
        {
            _logger = logger;
            _modelExecutionService = modelExecutionService;
            _mcpToolExecutionService = mcpToolExecutionService;
            _promptTemplateService = promptTemplateService;
            _conversationManager = conversationManager;
        }

        /// <summary>
        /// 执行Agent任务
        /// </summary>
        /// <param name="agent">Agent实体</param>
        /// <param name="input">执行输入</param>
        /// <returns>执行结果</returns>
        public async Task<AgentExecutionResult> ExecuteAsync(Agent agent, AgentExecutionInput input)
        {
            var executionId = Guid.NewGuid();
            _logger.LogInformation("开始执行Agent任务: {AgentName}, 执行ID: {ExecutionId}", agent.Name, executionId);

            try
            {
                // 验证Agent状态
                if (!agent.CanRun())
                {
                    throw new InvalidOperationException($"Agent {agent.Name} 当前状态无法执行: {agent.Status}");
                }

                // 更新Agent状态为运行中
                agent.Start();
                agent.ConfirmStarted();

                // 获取或创建会话
                var conversation = await _conversationManager.GetOrCreateConversationAsync(
                    input.ConversationId ?? Guid.NewGuid(),
                    agent.Id,
                    input.UserId);

                // 构建执行上下文
                var context = new AgentExecutionContext
                {
                    ExecutionId = executionId,
                    Agent = agent,
                    Conversation = conversation,
                    Input = input,
                    StartTime = DateTime.UtcNow
                };

                // 执行Agent逻辑
                var result = await ExecuteAgentLogicAsync(context);

                // 更新Agent统计信息
                if (result.Success)
                {
                    agent.RunCount++;
                }
                else
                {
                    agent.ErrorCount++;
                }

                agent.LastRunTime = DateTime.UtcNow;
                agent.Status = AgentStatus.Stopped;

                _logger.LogInformation("Agent任务执行完成: {AgentName}, 执行ID: {ExecutionId}, 成功: {Success}",
                    agent.Name, executionId, result.Success);

                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Agent任务执行异常: {AgentName}, 执行ID: {ExecutionId}", agent.Name, executionId);

                // 更新Agent状态为错误
                agent.SetError(ex.Message);

                return new AgentExecutionResult
                {
                    ExecutionId = executionId,
                    Success = false,
                    ErrorMessage = ex.Message,
                    ExecutionTimeMs = 0
                };
            }
        }

        /// <summary>
        /// 执行Agent核心逻辑
        /// </summary>
        /// <param name="context">执行上下文</param>
        /// <returns>执行结果</returns>
        private async Task<AgentExecutionResult> ExecuteAgentLogicAsync(AgentExecutionContext context)
        {
            var startTime = DateTime.UtcNow;

            try
            {
                // 1. 应用Prompt模板
                var systemPrompt = await ApplyPromptTemplateAsync(context);

                // 2. 构建消息历史
                var messages = await BuildMessagesAsync(context, systemPrompt);

                // 3. 执行多轮对话（可能包含工具调用）
                var finalResult = await ExecuteMultiTurnConversationAsync(context, messages);

                // 4. 保存对话记录
                await SaveConversationAsync(context, finalResult);

                return new AgentExecutionResult
                {
                    ExecutionId = context.ExecutionId,
                    Success = true,
                    Response = finalResult.Response,
                    ToolCalls = finalResult.ToolCalls,
                    TokensUsed = finalResult.TokensUsed,
                    ExecutionTimeMs = (int)(DateTime.UtcNow - startTime).TotalMilliseconds
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Agent逻辑执行异常: {ExecutionId}", context.ExecutionId);
                return new AgentExecutionResult
                {
                    ExecutionId = context.ExecutionId,
                    Success = false,
                    ErrorMessage = ex.Message,
                    ExecutionTimeMs = (int)(DateTime.UtcNow - startTime).TotalMilliseconds
                };
            }
        }

        /// <summary>
        /// 应用Prompt模板
        /// </summary>
        /// <param name="context">执行上下文</param>
        /// <returns>处理后的系统提示词</returns>
        private async Task<string> ApplyPromptTemplateAsync(AgentExecutionContext context)
        {
            var systemPrompt = context.Agent.SystemPrompt;

            // 如果Agent配置了Prompt模板，则应用模板
            if (context.Agent.PromptTemplateId.HasValue)
            {
                try
                {
                    var templateResult = await _promptTemplateService.ApplyTemplateAsync(
                        context.Agent.PromptTemplateId.Value,
                        new Dictionary<string, object>
                        {
                            { "system_prompt", systemPrompt },
                            { "user_input", context.Input.UserInput },
                            { "agent_name", context.Agent.Name },
                            { "agent_description", context.Agent.Description },
                            { "context", context.Input.Context ?? new Dictionary<string, object>() }
                        });

                    return templateResult.ProcessedPrompt;
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, "应用Prompt模板失败，使用原始系统提示词: {ExecutionId}", context.ExecutionId);
                    return systemPrompt;
                }
            }

            return systemPrompt;
        }

        /// <summary>
        /// 构建消息历史
        /// </summary>
        /// <param name="context">执行上下文</param>
        /// <param name="systemPrompt">系统提示词</param>
        /// <returns>消息列表</returns>
        private async Task<List<ChatMessage>> BuildMessagesAsync(AgentExecutionContext context, string systemPrompt)
        {
            var messages = new List<ChatMessage>();

            // 添加系统消息
            if (!string.IsNullOrWhiteSpace(systemPrompt))
            {
                messages.Add(new ChatMessage { Role = "system", Content = systemPrompt });
            }

            // 获取历史对话记录
            var history = await _conversationManager.GetConversationHistoryAsync(
                context.Conversation.Id,
                maxMessages: 10); // 限制历史消息数量

            // 添加历史消息
            foreach (var msg in history)
            {
                messages.Add(new ChatMessage { Role = msg.Role, Content = msg.Content });
            }

            // 添加当前用户输入
            messages.Add(new ChatMessage { Role = "user", Content = context.Input.UserInput });

            return messages;
        }

        /// <summary>
        /// 执行多轮对话
        /// </summary>
        /// <param name="context">执行上下文</param>
        /// <param name="messages">消息列表</param>
        /// <returns>最终对话结果</returns>
        private async Task<ConversationTurnResult> ExecuteMultiTurnConversationAsync(AgentExecutionContext context, List<ChatMessage> messages)
        {
            const int maxTurns = 10; // 最大轮次限制，防止无限循环
            var currentTurn = 0;
            var currentMessages = new List<ChatMessage>(messages);
            var finalResult = new ConversationTurnResult();

            while (currentTurn < maxTurns)
            {
                currentTurn++;
                _logger.LogDebug("执行第 {Turn} 轮对话: {ExecutionId}", currentTurn, context.ExecutionId);

                // 获取模型配置
                var modelConfig = await GetModelConfigAsync(context.Agent.ModelConfigId);
                if (modelConfig == null)
                {
                    throw new InvalidOperationException($"未找到模型配置: {context.Agent.ModelConfigId}");
                }

                // 调用大模型
                var modelResult = await _modelExecutionService.ExecuteModelAsync(modelConfig, new ModelExecutionInput
                {
                    Messages = currentMessages,
                    MaxTokens = 4000, // 使用默认值或从modelConfig中获取
                    Temperature = 0.7, // 使用默认值或从modelConfig中获取
                    TimeoutSeconds = 30, // 使用默认值或从modelConfig中获取
                    UserId = context.Input.UserId,
                    SessionId = context.Conversation.Id
                });

                // 添加助手回复到消息历史
                currentMessages.Add(new ChatMessage { Role = "assistant", Content = modelResult.Response });

                // 检查是否需要调用工具
                if (modelResult.ToolCalls != null && modelResult.ToolCalls.Count > 0)
                {
                    // 执行工具调用
                    var toolResults = await ExecuteToolCallsAsync(context, modelResult.ToolCalls);

                    // 将工具调用结果添加到消息历史
                    foreach (var toolResult in toolResults)
                    {
                        currentMessages.Add(new ChatMessage
                        {
                            Role = "tool",
                            Content = JsonSerializer.Serialize(toolResult.Result),
                            ToolCallId = toolResult.ToolCallId,
                            ToolName = toolResult.ToolName
                        });
                    }

                    // 继续下一轮对话
                    finalResult.ToolCalls?.AddRange(toolResults);
                    finalResult.TokensUsed += modelResult.TokensUsed;
                    continue;
                }

                // 没有工具调用，对话结束
                finalResult.Response = modelResult.Response;
                finalResult.TokensUsed += modelResult.TokensUsed;
                break;
            }

            if (currentTurn >= maxTurns)
            {
                _logger.LogWarning("达到最大对话轮次限制: {ExecutionId}", context.ExecutionId);
                finalResult.Response += "\n\n[注意：已达到最大对话轮次限制]";
            }

            return finalResult;
        }

        /// <summary>
        /// 执行工具调用
        /// </summary>
        /// <param name="context">执行上下文</param>
        /// <param name="toolCalls">工具调用列表</param>
        /// <returns>工具调用结果列表</returns>
        private async Task<List<ToolCallResult>> ExecuteToolCallsAsync(AgentExecutionContext context, List<ToolCall> toolCalls)
        {
            var results = new List<ToolCallResult>();

            foreach (var toolCall in toolCalls)
            {
                try
                {
                    _logger.LogDebug("执行工具调用: {ToolName}, 参数: {Parameters}",
                        toolCall.Name, JsonSerializer.Serialize(toolCall.Parameters));

                    var result = await _mcpToolExecutionService.ExecuteToolAsync(new McpToolExecutionInput
                    {
                        ToolName = toolCall.Name,
                        Parameters = toolCall.Parameters,
                        TimeoutSeconds = 30 // 使用默认值
                    });

                    results.Add(new ToolCallResult
                    {
                        ToolCallId = toolCall.Id,
                        ToolName = toolCall.Name,
                        Result = result.Result,
                        Success = result.Success,
                        ErrorMessage = result.ErrorMessage
                    });

                    _logger.LogDebug("工具调用完成: {ToolName}, 成功: {Success}",
                        toolCall.Name, result.Success);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "工具调用异常: {ToolName}", toolCall.Name);
                    results.Add(new ToolCallResult
                    {
                        ToolCallId = toolCall.Id,
                        ToolName = toolCall.Name,
                        Success = false,
                        ErrorMessage = ex.Message
                    });
                }
            }

            return results;
        }

        /// <summary>
        /// 保存对话记录
        /// </summary>
        /// <param name="context">执行上下文</param>
        /// <param name="result">对话结果</param>
        private async Task SaveConversationAsync(AgentExecutionContext context, ConversationTurnResult result)
        {
            try
            {
                await _conversationManager.AddMessageAsync(context.Conversation.Id, new ConversationMessage
                {
                    Role = "user",
                    Content = context.Input.UserInput,
                    Timestamp = DateTime.UtcNow
                });

                await _conversationManager.AddMessageAsync(context.Conversation.Id, new ConversationMessage
                {
                    Role = "assistant",
                    Content = result.Response,
                    Timestamp = DateTime.UtcNow,
                    ToolCalls = result.ToolCalls,
                    TokensUsed = result.TokensUsed
                });

                // 更新会话的最后活动时间
                await _conversationManager.UpdateConversationActivityAsync(context.Conversation.Id);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "保存对话记录失败: {ExecutionId}", context.ExecutionId);
            }
        }

        /// <summary>
        /// 获取模型配置
        /// </summary>
        /// <param name="modelConfigId">模型配置ID</param>
        /// <returns>模型配置实体</returns>
        private async Task<ModelConfig> GetModelConfigAsync(Guid? modelConfigId)
        {
            if (!modelConfigId.HasValue)
                return null;

            // 这里应该通过仓储获取模型配置，暂时简化实现
            // TODO: 注入IRepository<ModelConfig, Guid>并正确获取配置
            return null;
        }
    }

    /// <summary>
    /// Agent执行上下文
    /// </summary>
    public class AgentExecutionContext
    {
        public Guid ExecutionId { get; set; }
        public Agent Agent { get; set; }
        public Conversation Conversation { get; set; }
        public AgentExecutionInput Input { get; set; }
        public DateTime StartTime { get; set; }
    }

    /// <summary>
    /// Agent执行输入
    /// </summary>
    public class AgentExecutionInput
    {
        public string UserInput { get; set; }
        public Guid? ConversationId { get; set; }
        public Guid UserId { get; set; }
        public Dictionary<string, object> Context { get; set; }
    }

    /// <summary>
    /// Agent执行结果
    /// </summary>
    public class AgentExecutionResult
    {
        public Guid ExecutionId { get; set; }
        public bool Success { get; set; }
        public string Response { get; set; }
        public string ErrorMessage { get; set; }
        public List<ToolCallResult> ToolCalls { get; set; }
        public long TokensUsed { get; set; }
        public int ExecutionTimeMs { get; set; }
    }

    /// <summary>
    /// 对话轮次结果
    /// </summary>
    public class ConversationTurnResult
    {
        public string Response { get; set; }
        public List<ToolCallResult> ToolCalls { get; set; } = new List<ToolCallResult>();
        public long TokensUsed { get; set; }
    }

    /// <summary>
    /// Agent聊天消息 - 使用统一的ChatMessage类型
    /// </summary>
    public class AgentChatMessage : ChatMessage
    {
    }

    /// <summary>
    /// Agent工具调用 - 使用统一的ToolCall类型
    /// </summary>
    public class AgentToolCall : ToolCall
    {
    }

    /// <summary>
    /// 工具调用结果
    /// </summary>
    public class ToolCallResult
    {
        public string ToolCallId { get; set; }
        public string ToolName { get; set; }
        public object Result { get; set; }
        public bool Success { get; set; }
        public string ErrorMessage { get; set; }
    }

    /// <summary>
    /// 用户友好异常 - 使用统一的UserFriendlyException类型
    /// </summary>
    public class AgentUserFriendlyException : UserFriendlyException
    {
        public AgentUserFriendlyException(string message) : base(message) { }
        public AgentUserFriendlyException(string message, Exception innerException) : base(message, innerException) { }
    }

    /// <summary>
    /// 模型执行输入
    /// </summary>
    public class ModelExecutionInput
    {
        public List<ChatMessage> Messages { get; set; }
        public int MaxTokens { get; set; }
        public double Temperature { get; set; }
        public int TimeoutSeconds { get; set; }
        public Guid UserId { get; set; }
        public Guid SessionId { get; set; }
    }

    /// <summary>
    /// 模型执行结果
    /// </summary>
    public class ModelExecutionResult
    {
        public string Response { get; set; }
        public List<ToolCall> ToolCalls { get; set; }
        public long TokensUsed { get; set; }
        public bool Success { get; set; }
        public string ErrorMessage { get; set; }
        public Dictionary<string, object> Metadata { get; set; }
    }

    
    /// <summary>
    /// 对话消息
    /// </summary>
    public class ConversationMessage
    {
        public string Role { get; set; }
        public string Content { get; set; }
        public DateTime Timestamp { get; set; }
        public List<ToolCallResult> ToolCalls { get; set; }
        public long TokensUsed { get; set; }
    }

    public interface IModelExecutionService
    {
        Task<ModelExecutionResult> ExecuteModelAsync(ModelConfig modelConfig, ModelExecutionInput input);
    }

    public interface IMcpToolExecutionService
    {
        Task<McpToolExecutionResult> ExecuteToolAsync(McpToolExecutionInput input);
    }

    public interface IPromptTemplateService
    {
        Task<PromptTemplateResult> ApplyTemplateAsync(Guid templateId, Dictionary<string, object> variables);
    }

    public interface IConversationManager
    {
        Task<Conversation> GetOrCreateConversationAsync(Guid conversationId, Guid agentId, Guid userId);
        Task<List<ConversationMessage>> GetConversationHistoryAsync(Guid conversationId, int maxMessages = 50);
        Task AddMessageAsync(Guid conversationId, ConversationMessage message);
        Task UpdateConversationActivityAsync(Guid conversationId);
    }

    public class PromptTemplateResult
    {
        public string ProcessedPrompt { get; set; }
        public bool Success { get; set; }
        public string ErrorMessage { get; set; }
    }
}